package com.yc.springmvc.web;

import com.google.gson.Gson;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.List;

public class MyDispatchServlet extends HttpServlet {


    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String requestURI = req.getRequestURI();
        //替换/sprin-mvc
        requestURI = requestURI.replace(req.getContextPath(), "");

        //根据 URI=》  空位控制器 =》省略
        IndexController controller = new IndexController();

        //判断响应当前请求   不包含继承的方法
        Method[] methods = controller.getClass().getDeclaredMethods();
        //控制器方法
        Method handlerMethod = null;
        for (Method method : methods) {
            RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
            if (requestMapping != null) {
                String path = requestMapping.value()[0];
                if (path.startsWith("/") == false) {
                    path = "/" + path;
                }
                if (path.equals((requestURI))){
                    handlerMethod = method;
                    break;
                }
            }
        }
        if (handlerMethod == null){
            //如果有DefaultServlet =>
            //如果没有 =》静态资源映射
            //如果还没有 => 404
            return;
        }
        //方法的参数集合
        Parameter[] parameters = handlerMethod.getParameters();
        //方法参数值集合
        List<Object> paramValues = new ArrayList<>();
        for (Parameter parameter : parameters){
            //提取请求中对应的参数值
            String value = req.getParameter(parameter.getName());
            //转型
            if (parameter.getType().isAssignableFrom(String.class)){
                paramValues.add(value);
            }else if (parameter.getType().isAssignableFrom(int.class) ||
                    parameter.getType().isAssignableFrom(Integer.class)){
                paramValues.add(Integer.valueOf(value));
            }else {
                //实体对象
                //拓展
            }
        }try {
            Object result = handlerMethod.invoke(controller, paramValues.toArray());
            if (controller.getClass().getAnnotation(RestController.class) != null){
                //@RestController => JSON modelandview
                if (result instanceof ModelAndView){
                    //跳转页面
                }else {
                    Gson gson = new Gson();
                    String json = gson.toJson(result);
                    resp.setContentType("application/json;charset=UTF-8");
                    resp.getWriter().append(json);
                }
            } else if (controller.getClass().getAnnotation(Controller.class) != null){
                if (handlerMethod.getAnnotation(ResponseBody.class) != null){
                    //转json

                }else {
                    //根据controller的注解
                    //@contoller =》响应重定向
                    String address = (String) result;
                    address = address.substring("redirect:".length());
                    resp.sendRedirect(address);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("执行控制方法失败",e);
        }
    }
}
